package cc.alcina.template.cs.persistent;

// Generated Sep 20, 2008 12:40:03 PM by Hibernate Tools 3.2.2.GA
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import cc.alcina.framework.common.client.actions.instances.CreateAction;
import cc.alcina.framework.common.client.actions.instances.DeleteAction;
import cc.alcina.framework.common.client.actions.instances.EditAction;
import cc.alcina.framework.common.client.actions.instances.ViewAction;
import cc.alcina.framework.common.client.logic.domaintransform.AlcinaPersistentEntityImpl;
import cc.alcina.framework.common.client.logic.domaintransform.spi.AccessLevel;
import cc.alcina.framework.common.client.logic.permissions.IGroup;
import cc.alcina.framework.common.client.logic.permissions.IUser;
import cc.alcina.framework.common.client.logic.reflection.Action;
import cc.alcina.framework.common.client.logic.reflection.Association;
import cc.alcina.framework.common.client.logic.reflection.BeanInfo;
import cc.alcina.framework.common.client.logic.reflection.CustomiserInfo;
import cc.alcina.framework.common.client.logic.reflection.DisplayInfo;
import cc.alcina.framework.common.client.logic.reflection.ObjectActions;
import cc.alcina.framework.common.client.logic.reflection.ObjectPermissions;
import cc.alcina.framework.common.client.logic.reflection.Permission;
import cc.alcina.framework.common.client.logic.reflection.PropertyPermissions;
import cc.alcina.framework.common.client.logic.reflection.RegistryLocation;
import cc.alcina.framework.common.client.logic.reflection.VisualiserInfo;

import cc.alcina.framework.gwt.client.gwittir.customiser.SelectorCustomiser;

import com.totsp.gwittir.client.beans.annotations.Introspectable;

/**
 * Group generated by hbm2java
 */
@Entity
@Table(name = "groups", schema = "public")
@SequenceGenerator(allocationSize=1,name = "groups_id_seq", sequenceName = "groups_id_seq")
@BeanInfo(actions = @ObjectActions( { @Action(actionClass = ViewAction.class),
		@Action(actionClass = EditAction.class),
		@Action(actionClass = CreateAction.class),
		@Action(actionClass = DeleteAction.class) }), displayNamePropertyName = "groupName")
@ObjectPermissions(create = @Permission(access = AccessLevel.ADMIN), delete = @Permission(access = AccessLevel.ADMIN))

@Introspectable
@RegistryLocation(registryPoint = AlcinaPersistentEntityImpl.class, targetClass = IGroup.class)
public class AlcinaTemplateGroup extends DomainBaseVersionable implements IGroup,
		 Comparable<AlcinaTemplateGroup> {
	private long id;

	private String groupName;

	Set<AlcinaTemplateGroup> memberGroups = new HashSet<AlcinaTemplateGroup>();

	private Set<AlcinaTemplateGroup> memberOfGroups = new HashSet<AlcinaTemplateGroup>();

	Set<AlcinaTemplateUser> memberUsers = new HashSet<AlcinaTemplateUser>();

	public AlcinaTemplateGroup() {
	}

	public AlcinaTemplateGroup(long id) {
		this.id = id;
	}

	public AlcinaTemplateGroup(long id, String groupName
			) {
		this.id = id;
		this.groupName = groupName;
		
	}

	public int compareTo(AlcinaTemplateGroup o) {
		return _compareTo(o);
	}

	@Override
	protected String comparisonString() {
		if (comparisonString != null) {
			return comparisonString;
		}
		comparisonString = getGroupName() == null ? null : getGroupName()
				.toLowerCase();
		return comparisonString;
	}

	@Column(name = "group_name")
	@VisualiserInfo(displayInfo = @DisplayInfo(name = "Name", orderingHint = 1))
	@PropertyPermissions(read = @Permission(access = AccessLevel.EVERYONE), write = @Permission(access = AccessLevel.ADMIN))
	public String getGroupName() {
		return this.groupName;
	}

	@Id
	@Column(name = "id", unique = true, nullable = false)
	@GeneratedValue(generator = "groups_id_seq")
	public long getId() {
		return this.id;
	}

	@ManyToMany( targetEntity = AlcinaTemplateGroup.class)
	@JoinTable(name = "group_group", joinColumns = @JoinColumn(name = "src_group_id"), inverseJoinColumns = @JoinColumn(name = "tgt_group_id"))
	@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
	@VisualiserInfo(displayInfo = @DisplayInfo(name = "Member groups", orderingHint = 91) )
	@Association(implementationClass = AlcinaTemplateGroup.class, propertyName="memberOfGroups")
	@PropertyPermissions(read = @Permission(access = AccessLevel.EVERYONE), write = @Permission(access = AccessLevel.ADMIN))
	@CustomiserInfo(customiserClass = SelectorCustomiser.class )
	public Set<AlcinaTemplateGroup> getMemberGroups() {
		return this.memberGroups;
	}

	@ManyToMany( mappedBy = "memberGroups", targetEntity = AlcinaTemplateGroup.class)
	@VisualiserInfo(displayInfo = @DisplayInfo(name = "Member of groups", orderingHint = 92))
@Association(implementationClass=AlcinaTemplateGroup.class,propertyName="memberGroups")
	@PropertyPermissions(read = @Permission(access = AccessLevel.EVERYONE), write = @Permission(access = AccessLevel.ADMIN))
	@CustomiserInfo(customiserClass = SelectorCustomiser.class )
	public Set<AlcinaTemplateGroup> getMemberOfGroups() {
		return memberOfGroups;
	}

	@ManyToMany( targetEntity = AlcinaTemplateUser.class)
	@JoinTable(name = "user_group", joinColumns = @JoinColumn(name = "group_id"), inverseJoinColumns = @JoinColumn(name = "user_id"))
	@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
	@VisualiserInfo(displayInfo = @DisplayInfo(name = "Member users", orderingHint = 90))
@Association(implementationClass=AlcinaTemplateUser.class,propertyName="secondaryGroups")
	@CustomiserInfo(customiserClass = SelectorCustomiser.class)
	@PropertyPermissions(read = @Permission(access = AccessLevel.EVERYONE), write = @Permission(access = AccessLevel.ADMIN))
	public Set<AlcinaTemplateUser> getMemberUsers() {
		return this.memberUsers;
	}

	/**
	 * Compatibility with IGroup
	 * 
	 * @see cc.alcina.framework.common.client.logic.permissions.IGroup#getName()
	 */
	@Transient
	public String getName() {
		return getGroupName();
	}

	public Set<IGroup> listMemberGroups() {
		throw new UnsupportedOperationException();
	}

	public Set<IUser> listMemberUsers() {
		throw new UnsupportedOperationException();
	}

	public void setGroupName(String groupName) {
		String old_groupName = this.groupName;
		this.groupName = groupName;
		propertyChangeSupport().firePropertyChange("groupName", old_groupName,
				groupName);
		this.groupName = groupName;
		comparisonString = groupName == null ? null : groupName.toLowerCase();
	}

	public void setId(long id) {
		this.id = id;
	}
	@SuppressWarnings("unchecked")
	public void setMemberGroups(Set<? extends IGroup> memberGroups) {
		Set<? extends IGroup> old_memberGroups = this.memberGroups;
		this.memberGroups = (Set<AlcinaTemplateGroup>) memberGroups;
		propertyChangeSupport().firePropertyChange("memberGroups",
				old_memberGroups, memberGroups);
	}

	// TODO: 3.2 - groupname uniqueness (should really be enforced at db level
	// too)
	public void setMemberOfGroups(Set<AlcinaTemplateGroup> memberOfGroups) {
		Set<AlcinaTemplateGroup> old_memberOfGroups = this.memberOfGroups;
		this.memberOfGroups = memberOfGroups;
		propertyChangeSupport().firePropertyChange("memberOfGroups",
				old_memberOfGroups, memberOfGroups);
	}
	@SuppressWarnings("unchecked")
	public void setMemberUsers(Set<? extends IUser> memberUsers) {
		Set<AlcinaTemplateUser> old_memberUsers = this.memberUsers;
		this.memberUsers = (Set<AlcinaTemplateUser>) memberUsers;
		propertyChangeSupport().firePropertyChange("memberUsers",
				old_memberUsers, memberUsers);
	}
}
